package com.yao.seckill.web.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yao.seckill.core.SeckillResponse;
import com.yao.seckill.web.constant.RabbitConstant;
import com.yao.seckill.web.enums.RabbitmqEnum;
import com.yao.seckill.web.pojo.RabbitConfirmMsg;
import com.yao.seckill.web.service.IRabbitConfirmMsgService;
import com.yao.seckill.web.service.RabbitService;
import com.yao.seckill.web.vo.RabbitVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Copyright (C), 2022-2022, 姚兵
 * Author: 32210
 * Date: 2022/9/16 12:36
 * FileName: RabbitServiceImpl
 * Description: rabbit
 */
@Service
@Slf4j
public class RabbitServiceImpl implements RabbitService {

    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    IRabbitConfirmMsgService rabbitConfirmMsgService;

    private ConcurrentHashMap map=new ConcurrentHashMap();
    @Override
    public SeckillResponse send(String msg) {

        log.info("send msg={}",msg);

        String msgId = UUID.randomUUID().toString();
        RabbitVo rabbitVo = RabbitVo.builder().rabbitId(msgId).msg(msg).build();
        CorrelationData correlationData = new CorrelationData(msgId);
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setMessageId(msgId);
        messageProperties.setCorrelationId(msgId);
        Message message = new Message(JSONObject.toJSONBytes(rabbitVo), messageProperties);
        ReturnedMessage returnedMessage = new ReturnedMessage(message,0,"123", RabbitConstant.DemoQueue.DEMO_EXCHANGE,RabbitConstant.DemoQueue.DEMO_ROUTING_KEY);
        correlationData.setReturned(returnedMessage);
//        rabbitTemplate.convertAndSend(RabbitConstant.DemoQueue.DEMO_EXCHANGE,
//                RabbitConstant.DemoQueue.DEMO_ROUTING_KEY,rabbitVo,correlationData);
        rabbitTemplate.convertAndSend(returnedMessage.getExchange(),
                returnedMessage.getRoutingKey(),rabbitVo,correlationData);
        log.info("send success msg={}",msg);
        return SeckillResponse.success();
    }

    @Override
    @Async//异步执行保存数据库操作
    public void saveMsgToDb(CorrelationData correlationData, boolean ack,String cause) {
        log.info("saveMsgToDb correlationData={} cause={}", JSONObject.toJSONString(correlationData),cause);

        RabbitConfirmMsg confirmMsg = buildMsg(correlationData,ack,cause);

        this.rabbitConfirmMsgService.save(confirmMsg);
    }

    
    private RabbitConfirmMsg buildMsg(CorrelationData data,boolean ack,String cause){
        RabbitConfirmMsg confirmMsg = new RabbitConfirmMsg();
        confirmMsg.setCause(cause);
        ReturnedMessage returned = data.getReturned();
        confirmMsg.setBody(new String(returned.getMessage().getBody()));
        confirmMsg.setExchange(returned.getExchange());
        confirmMsg.setCorrelationDataId(data.getId());
        confirmMsg.setCreateTime(LocalDateTime.now());
        confirmMsg.setReplyCode(returned.getReplyCode());
        confirmMsg.setReplyText(returned.getReplyText());
        confirmMsg.setStatus(ack?RabbitmqEnum.ConfirmStatus.SUCCESS.getStatus():RabbitmqEnum.ConfirmStatus.FAILURE.getStatus());
        confirmMsg.setRoutingKey(returned.getRoutingKey());

        return confirmMsg;
    }
}
